﻿
using System;
using System.IO;

namespace streamsearcher
{
    public sealed class StreamSearcher
    {
        public const int MAX_PATTERN_LENGTH = 1024;
        private readonly int[] _borders;
        private readonly byte[] _pattern;

        public StreamSearcher(byte[] pattern)
        {
            _pattern = new byte[pattern.Length];
            Array.Copy(pattern, _pattern, pattern.Length);
            _borders = new int[_pattern.Length + 1];
            preProcess();
        }


        private void preProcess()
        {
            var i = 0;
            var j = -1;
            _borders[i] = j;

            while (i < _pattern.Length)
            {
                while (j >= 0 && _pattern[i] != _pattern[j])
                {
                    j = _borders[j];
                }
                _borders[++i] = ++j;
            }
        }


        public long Search(Stream stream) //KMP搜索算法
        {
            long bytesRead = 0;

            int b;
            var j = 0;

            while ((b = stream.ReadByte()) != -1)
            {
                bytesRead++;

                while (j >= 0 && (byte) b != _pattern[j])
                {
                    j = _borders[j];
                }

                ++j;


                if (j == _pattern.Length)
                {
                    return bytesRead;
                }
            }

            return -1;
        }
    }
}